package cn.iocoder.yudao.module.system.service.workstore;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.module.system.controller.admin.workstorepallet.vo.WorkStorePalletRespVO;
import cn.iocoder.yudao.module.system.controller.admin.workstorepallet.vo.WorkStorePalletSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.dataobject.workorder.WorkOrderDO;
import cn.iocoder.yudao.module.system.dal.dataobject.workstorepallet.WorkStorePalletDO;
import cn.iocoder.yudao.module.system.dal.dataobject.workstroerecord.WorkStroeRecordDO;
import cn.iocoder.yudao.module.system.dal.mysql.workorder.WorkOrderMapper;
import cn.iocoder.yudao.module.system.dal.mysql.workstorepallet.WorkStorePalletMapper;
import cn.iocoder.yudao.module.system.dal.mysql.workstroerecord.WorkStroeRecordMapper;
import cn.iocoder.yudao.module.system.util.QRCodeUtil;
import cn.iocoder.yudao.module.system.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import cn.iocoder.yudao.module.system.controller.admin.workstore.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.workstore.WorkStoreDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.system.dal.mysql.workstore.WorkStoreMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;

/**
 * 工单入库 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class WorkStoreServiceImpl implements WorkStoreService {

    @Resource
    private WorkOrderMapper workOrderMapper;
    @Resource
    private WorkStoreMapper workStoreMapper;
    @Resource
    private WorkStorePalletMapper workStorePalletMapper;
    @Resource
    private WorkStroeRecordMapper workStroeRecordMapper;
    @Value("${system.image-user-write-path}")
    String imageUserWritePath;
    @Value("${system.image-user-path}")
    String imageUserPath;
    @Value("${system.image-host}")
    String imageHost;
    /**
     * 生成订单二维码
     * @return 二维码链接
     */
    private String createQRCodes(String qrcodeString) {
        byte[] bytes = qrcodeString.getBytes();
//        Base64.Encoder encoder = Base64.getEncoder();
//        String base64String = encoder.encodeToString(bytes);
        String fileName = RandomUtil.getRandomImageFileName();
        QRCodeUtil.createCodeToFile(qrcodeString, new File(imageUserWritePath), fileName);
        return imageHost+imageUserPath+fileName;
    }

    @Override
    public Integer createWorkStore(List<WorkStoreSaveReqVO> createReqVOs) {
        Integer id = 0;
        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        // 格式化日期
        String formattedDate = today.format(formatter);
        List<WorkStorePalletDO> workStorePalletDOS = new ArrayList<>();
        List<WorkStroeRecordDO> workStroeRecordDOS = new ArrayList<>();
        List<Integer> workids = new ArrayList<>();
        workids.add(0);
        for (WorkStoreSaveReqVO createReqVO:createReqVOs) {
            if(!workids.contains(createReqVO.getWorkId())){
                workids.add(createReqVO.getWorkId());
            }
        }
        QueryWrapper<WorkOrderDO> workOrderDOQueryWrapper = new QueryWrapper<>();
        workOrderDOQueryWrapper.in("work_id",workids);
        List<WorkOrderDO> workOrderDOS = workOrderMapper.selectList(workOrderDOQueryWrapper);
        for (WorkStoreSaveReqVO createReqVO:createReqVOs) {
            QueryWrapper<WorkStoreDO> storeDOQueryWrapper = new QueryWrapper<>();
            storeDOQueryWrapper.eq("work_id",createReqVO.getWorkId());
            Long num = workStoreMapper.selectCount(storeDOQueryWrapper);
            num = num+1;
            // 插入
            WorkStoreDO workStore = BeanUtils.toBean(createReqVO, WorkStoreDO.class);
            workStore.setBatchNumber(formattedDate+"-"+num);
            for (WorkOrderDO item2:workOrderDOS) {
                if(item2.getId().equals(Long.valueOf(createReqVO.getWorkId()))){
                    workStore.setCustomerId(item2.getCustomerId());
                    break;
                }
            }
            workStoreMapper.insert(workStore);
            id = workStore.getId();
            Integer incomingZnum = 0;
            for (WorkStorePalletSaveReqVO item:createReqVO.getWorkStorePalletSaveReqVOS()) {
                incomingZnum = Integer.valueOf(incomingZnum+item.getIncomingNum());
            }
            //第几托
            Integer number = 1;
            for (WorkStorePalletSaveReqVO item:createReqVO.getWorkStorePalletSaveReqVOS()) {
                WorkStorePalletDO workStorePalletDO = BeanUtils.toBean(item, WorkStorePalletDO.class);
                workStorePalletDO.setWorkId(createReqVO.getWorkId());
                workStorePalletDO.setStoreId(workStore.getId());
                workStorePalletDOS.add(workStorePalletDO);
                double count2 = Double.parseDouble(item.getIncomingNum());

                int count = (int) Math.ceil(count2);
                if(createReqVO.getStorageMethod().equals("1")){
                    for (int i = 1; i <= count; i++) {
                        WorkStroeRecordDO workStoreRespVO = new WorkStroeRecordDO();
                        workStoreRespVO.setWorkId(createReqVO.getWorkId());
                        workStoreRespVO.setStoreId(workStore.getId());
                        workStoreRespVO.setIncomingNum(String.valueOf(incomingZnum));
                        workStoreRespVO.setNumber(number);
                        workStoreRespVO.setTotalNum(createReqVO.getTotalQuantity());

                        if(item.getBoxesNum()!=null&&!item.getBoxesNum().equals(0)){
                            workStoreRespVO.setPalletQuantity( item.getBoxNum().multiply(new BigDecimal(item.getBoxesNum())));
                            workStoreRespVO.setBoxNum( item.getBoxesNum());
                        }else{
                            workStoreRespVO.setPalletQuantity( item.getBoxNum().multiply(new BigDecimal(item.getIncomingNum())));
                            workStoreRespVO.setBoxNum( 0);
                        }
                        workStoreRespVO.setQrcode( createQRCodes("JYSDT:"+workStoreRespVO.getWorkId()+":"+workStoreRespVO.getStoreId()+":"+workStoreRespVO.getNumber()));
                        workStroeRecordDOS.add(workStoreRespVO);
                        number++;
                    }
                }else {
                    for (int i = 1; i <= count; i++) {
                        WorkStroeRecordDO workStoreRespVO = new WorkStroeRecordDO();
                        workStoreRespVO.setWorkId(createReqVO.getWorkId());
                        workStoreRespVO.setStoreId(workStore.getId());
                        workStoreRespVO.setIncomingNum(String.valueOf(incomingZnum));
                        workStoreRespVO.setNumber(number);
                        workStoreRespVO.setTotalNum(createReqVO.getTotalQuantity());
                        if(i<count){
                            workStoreRespVO.setPalletQuantity( item.getBoxNum());
                        }else{
                            workStoreRespVO.setPalletQuantity(createReqVO.getTotalQuantity().subtract(item.getBoxNum().multiply(new BigDecimal(count-1))));
                        }
                        workStoreRespVO.setQrcode( createQRCodes("JYSDT:"+workStoreRespVO.getWorkId()+":"+workStoreRespVO.getStoreId()+":"+workStoreRespVO.getNumber()));
                        workStroeRecordDOS.add(workStoreRespVO);
                        number++;
                    }
                }
            }
            //更新订单信息
            UpdateWrapper<WorkOrderDO> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id",createReqVO.getWorkId());
            if(createReqVO.getTotalQuantity().compareTo(BigDecimal.valueOf(0L))>0){
                updateWrapper.setSql("white_items_num = white_items_num + "+createReqVO.getTotalQuantity()+",inventory_quantity = inventory_quantity + "+createReqVO.getTotalQuantity()+",storage_method="+createReqVO.getStorageMethod());
            }else {
                updateWrapper.setSql("white_items_num = white_items_num + "+createReqVO.getTotalQuantity()+",inventory_quantity = inventory_quantity + "+createReqVO.getTotalQuantity()+",bp_defect_num = bp_defect_num - "+createReqVO.getTotalQuantity()+",storage_method="+createReqVO.getStorageMethod());
            }
            workOrderMapper.update(updateWrapper);
        }
        workStorePalletMapper.insertBatch(workStorePalletDOS);
        workStroeRecordMapper.insertBatch(workStroeRecordDOS);
        // 返回
        return id;
    }

    @Override
    public void updateWorkStore(WorkStoreSaveReqVO updateReqVO) {
        // 校验存在
        validateWorkStoreExists(updateReqVO.getId());
        // 更新
        WorkStoreDO updateObj = BeanUtils.toBean(updateReqVO, WorkStoreDO.class);
        workStoreMapper.updateById(updateObj);
    }

    @Override
    public void deleteWorkStore(Integer id) {
        // 校验存在
//        validateWorkStoreExists(id);
        WorkStoreDO workStoreDO = workStoreMapper.selectById(id);
        if(workStoreDO!=null&&workStoreDO.getRacking()>1){
            throw exception(WORK_STROE_RECORD_RACKING);
        }
        // 删除
        workStoreMapper.deleteById(id);
    }

    @Override
        public void deleteWorkStoreListByIds(List<Integer> ids) {
        // 校验存在
        validateWorkStoreExists(ids);
        // 删除
        workStoreMapper.deleteByIds(ids);
        }

    private void validateWorkStoreExists(List<Integer> ids) {
        List<WorkStoreDO> list = workStoreMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(WORK_STORE_NOT_EXISTS);
        }
    }

    private void validateWorkStoreExists(Integer id) {
        if (workStoreMapper.selectById(id) == null) {
            throw exception(WORK_STORE_NOT_EXISTS);
        }
    }

    @Override
    public WorkStoreRespVO getWorkStore(Integer id) {
        WorkStoreDO arr = workStoreMapper.selectById(id);
        WorkStoreRespVO data = BeanUtils.toBean(arr, WorkStoreRespVO.class);

        QueryWrapper<WorkStorePalletDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("store_id",id);
        List<WorkStorePalletDO> workStorePalletDOS = workStorePalletMapper.selectList(queryWrapper);

        List<WorkStorePalletRespVO> workStorePalletRespVOS = BeanUtils.toBean(workStorePalletDOS, WorkStorePalletRespVO.class);
        data.setWorkStorePalletRespVO(workStorePalletRespVOS);
        return data;

    }

    @Override
    public PageResult<WorkStoreRespVO> getWorkStorePage(WorkStorePageReqVO pageReqVO) {
        PageResult<WorkStoreDO> list = workStoreMapper.selectPage(pageReqVO);
        PageResult<WorkStoreRespVO> data = BeanUtils.toBean(list, WorkStoreRespVO.class);
        List<Integer> storeIds = new ArrayList<>();
        for (WorkStoreRespVO item:data.getList()) {
            storeIds.add(item.getId());
        }
        storeIds.add(0);
        QueryWrapper<WorkStorePalletDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("store_id",storeIds);
        List<WorkStorePalletDO> workStorePalletDOS = workStorePalletMapper.selectList(queryWrapper);

        for (WorkStoreRespVO item:data.getList()) {
            for (WorkStorePalletDO item2:workStorePalletDOS) {
                WorkStorePalletRespVO workStorePalletRespVO = BeanUtils.toBean(item2, WorkStorePalletRespVO.class);
                if (item.getId().equals(item2.getStoreId())){
                    List<WorkStorePalletRespVO> workStorePalletRespVOS = new ArrayList<>();
                    workStorePalletRespVOS.add(workStorePalletRespVO);
                    item.setWorkStorePalletRespVO(workStorePalletRespVOS);
                    break;
                }
            }
        }
        return data;
    }

}
